home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
tools
/
czesc_3
/
psm
/
source
/
tracking.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-28
|
5KB
|
203 lines
#include "psm.h"
UBYTE *sem_name = TITLENAME " V" FULL_VERSION " tracking semaphore";
struct track_sem {
struct SignalSemaphore sem;
struct List track_list;
};
struct track_entry {
struct Node node;
struct Screen *scrn;
struct List mem_list;
};
struct track_mem {
struct MinNode node;
};
static struct track_sem *get_track_sem(void)
{
struct track_sem *track;
Forbid();
if( !(track = (struct track_sem *)FindSemaphore(sem_name)) ) {
track = (struct track_sem *)
AllocVec(sizeof(struct track_sem),MEMF_PUBLIC|MEMF_CLEAR);
if(!track) {
Permit();
return NULL;
}
if( !(track->sem.ss_Link.ln_Name
= AllocVec(strlen(sem_name)+2,MEMF_PUBLIC)) ) {
Permit();
FreeVec(track);
return NULL;
}
strcpy(track->sem.ss_Link.ln_Name,sem_name);
track->sem.ss_Link.ln_Pri = 0;
InitSemaphore(&track->sem);
NewList(&track->track_list);
AddSemaphore(&track->sem);
}
ObtainSemaphore(&track->sem);
Permit();
return track;
}
// -----------------------------------------------
// Free all memory attached to a screen tracker.
// -----------------------------------------------
void FreeScrnTrack(void *scrn_track)
{
struct Node *ent;
if(!scrn_track) return;
while( (ent=RemTail(&((struct track_entry *)scrn_track)->mem_list)) ) {
FreeVec(ent);
}
FreeVec(scrn_track);
}
// -----------------------------------------------
// Allocate a new screen tracker.
// -----------------------------------------------
void *AllocScrnTrack(void)
{
struct track_entry *track;
if(!(track=AllocVec(sizeof(struct track_entry),MEMF_PUBLIC|MEMF_CLEAR))) {
return NULL;
}
NewList(&track->mem_list);
track->scrn = NULL;
return track;
}
// -----------------------------------------------
// Allocate a block of memory and attach it to the screen tracker.
// -----------------------------------------------
void *AllocScrnTrackMem(void *scrn_track,ULONG size)
{
void *mem;
size += sizeof(struct track_mem);
mem = AllocVec(size,MEMF_PUBLIC|MEMF_CLEAR);
if(mem) {
AddTail( &((struct track_entry *)scrn_track)->mem_list, mem );
return (void *)( ((ULONG)mem) + sizeof(struct track_mem) );
}
return NULL;
}
// -----------------------------------------------
// Add a completed screen tracker to the public list.
// -----------------------------------------------
void AddScrnTrack(void *scrn_track,struct Screen *scrn)
{
struct track_sem *sem;
if(!scrn_track) return;
if(scrn) {
((struct track_entry *)scrn_track)->scrn = scrn;
} else if(!((struct track_entry *)scrn_track)->scrn) {
FreeScrnTrack(scrn_track);
return;
}
if( (sem = get_track_sem()) ) {
AddTail(&sem->track_list,scrn_track);
ReleaseSemaphore(&sem->sem);
}
}
// -----------------------------------------------
// Find and remove the tracker attached to the given screen.
// -----------------------------------------------
void *GetScrnTrack(struct Screen *scrn)
{
struct track_sem *sem;
struct track_entry *ent;
if(!scrn) return NULL;
if( (sem = get_track_sem()) ) {
for(ent = head_node(&sem->track_list);
ent != NULL;
ent = next_node(ent)) {
if(ent->scrn == scrn) {
Remove(&ent->node);
ReleaseSemaphore(&sem->sem);
return ent;
}
}
ReleaseSemaphore(&sem->sem);
}
return NULL;
}
// -----------------------------------------------
// Check if the given screen is being tracked.
// -----------------------------------------------
void *CheckScrnTrack(struct Screen *scrn)
{
struct track_sem *sem;
struct track_entry *ent;
if(!scrn) return NULL;
if( (sem = get_track_sem()) ) {
for(ent = head_node(&sem->track_list);
ent != NULL;
ent = next_node(ent)) {
if(ent->scrn == scrn) {
ReleaseSemaphore(&sem->sem);
return ent;
}
}
ReleaseSemaphore(&sem->sem);
}
return NULL;
}
// -----------------------------------------------
// Close the screen and any memory we may be tracking.
// -----------------------------------------------
BOOL CloseScrnTrack(struct Screen *scrn)
{
struct track_entry *ent;
if(!scrn) return TRUE;
ent = GetScrnTrack(scrn);
if( CloseScreen(scrn) ) {
if(ent) FreeScrnTrack(ent);
return TRUE;
}
AddScrnTrack(ent,NULL);
return FALSE;
}